#include <string.h>
#include <QXmlStreamReader>
#include "mini2440client.h"
#include "mini2440ChangePassForm.h"
#include "mini2440InboxForm.h"
#include "mini2440SettingForm.h"

#define DEFAULT_INPUT_TIMEOUT 10000
#define SIZING_FACTOR_HEIGHT 5/10
#define SIZING_FACTOR_WIDTH 5/10
#define APP_INBOX_INDEX 1

Mini2440Client::Mini2440Client(QStringList* args)
{
    m_config = new mini2440Configuration();
    m_config->loadConfig();
    initDefaultValue();
    initComponent();
    initSocket();
    initConnection();
    initConfiguration(args);

    QObject::connect(mSetting,SIGNAL(saveSetting()),this,SLOT(save()));

}
void Mini2440Client::initDefaultValue()
{
    currentIndex = 0;
    m_ipAdress = "192.168.1.33";
    m_port = 8888;
}

void Mini2440Client::initComponent()
{
    currentIndex = -1;

    usInboxIndex            = APP_INBOX_INDEX;
    pictureFlowWidget       = new PictureFlow();
    screenSaveWidget        = new ScreenSave();
    inputTimer = new QTimer();

    screenSaveWidget->addImageDir(m_config->getScreenImageDir());
    messageSlideShowWidget  = new MessageScreenSave();
    messageSlideShowWidget->addImageDir(m_config->getMessageImageDir());



    addWidget(pictureFlowWidget);
    addWidget(screenSaveWidget);
    addWidget(messageSlideShowWidget);
    setCurrentWidget(pictureFlowWidget);
    pictureFlowWidget->setFocus();

    QRect screen_size = QApplication::desktop()->screenGeometry();
    inputTimer->setSingleShot(true);
    inputTimer->setInterval(m_config->get_screenTimeout());
    screenSaveWidget->setSlideInterval(m_config->get_screenInterval());


    const int h = screen_size.height() * SIZING_FACTOR_HEIGHT;
    const int w = screen_size.width() * SIZING_FACTOR_WIDTH;
    const int hh = qMin(h, w);
    const int ww = hh / 3 * 2;
    pictureFlowWidget->setSlideSize(QSize(ww, hh));
}

void Mini2440Client::initConfiguration(QStringList* args)
{
    if (true) {
      populatePictureFlow();

      this->setMinimumSize(500,600);
     // showFullScreen();
      this->showMinimized();
      inputTimer->start();
    } else {
        pictureFlowWidget->setAttribute(Qt::WA_DeleteOnClose, true);
        pictureFlowWidget->close();
    }
}

void Mini2440Client::initConnection()
{
    tcpSocket = new QTcpSocket(this);
    tcpSocket->connectToHost(m_config->getServerIP(),m_config->getServerPort());

    qDebug() << m_config->getServerIP() << m_config->getServerPort();
    QObject::connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(recievedData()));
    //connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
    //connect(ui->action_Quit, SIGNAL(clicked()), this, SLOT(close()));
    //QObject::connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
      //      this, SLOT(displayError(QAbstractSocket::SocketError)));

    QObject::connect(pictureFlowWidget,         SIGNAL(itemActivated(int)),
                     this, SLOT(launchApplication(int)));
    QObject::connect(pictureFlowWidget,     SIGNAL(inputReceived()),
                     this, SLOT(resetInputTimeout()));
    QObject::connect(pictureFlowWidget,     SIGNAL(slideActived()),
                     this, SLOT(inputTimedout()));
    QObject::connect(pictureFlowWidget,     SIGNAL(newMessage()),
                     this, SLOT(recievedNewMessageSignal()));
    QObject::connect(pictureFlowWidget,     SIGNAL(wrongpass()),
                     this, SLOT(recievedWrogpassSignal()));

    QObject::connect(screenSaveWidget,      SIGNAL(inputReceived()),
                     this, SLOT(switchToLauncher()));
    QObject::connect(screenSaveWidget,       SIGNAL(newMessageRecived()),
                     this, SLOT(recievedNewMessageSignal()));

    QObject::connect(messageSlideShowWidget, SIGNAL(readNewMessage()),
                     this, SLOT(recievedReadNewMessageSignal()));

    QObject::connect(inputTimer,             SIGNAL(timeout()),
                     this, SLOT(inputTimedout()));

}

void Mini2440Client::initSocket()
{

}

void Mini2440Client::recievedData()
{
    QByteArray block;
    QTextCodec* codec = QTextCodec::codecForName("UTF-16LE");
    QDataStream in(&block, QIODevice::ReadOnly);
    in.setVersion(QDataStream::Qt_4_0);
    in.setByteOrder(QDataStream::LittleEndian);

    block = tcpSocket->read(14);
    int totalBytes = 0;
     std::string temp ;
    quint16 command = 0x000;
    in >> totalBytes >> command;// >> len1 >> len2;
    switch(command)
    {
    case 0x114:
        //mConfig = new mini2440Configuration;
        m_config->resetPass();
        QMessageBox::about(0,"FUEMES Server",QString::fromUtf8("Mật khẩu đã được reset"));
        break;
    case 0x115:
        temp = QDir::currentPath().toStdString();
        int len1,len2;
        len1 = 0;
        len2 = 0;
        in >> len1 >> len2;
        if ((len1+len2+10) != totalBytes)
            return;
        block = tcpSocket->read(len1);
        QString subject = codec->toUnicode(block);
        block = tcpSocket->read(len2);
        QString content = codec->toUnicode(block);
//save file
        QFile file(subject+".msg");
        QDir::setCurrent("./Mess");
        if (!file.open(QFile::WriteOnly | QFile::Text)) {
            QMessageBox::warning(this, tr("Application"),
                                 tr("Cannot write file %1:\n%2.")
                                 .arg(subject)
                                 .arg(file.errorString()));
            return ;
        }

       // path.remove(path.length()-5,path.length());
        QDir::setCurrent(QString().fromStdString(temp));
        QTextStream out(&file);
    #ifndef QT_NO_CURSOR
        QApplication::setOverrideCursor(Qt::WaitCursor);
    #endif
        out << content;
    #ifndef QT_NO_CURSOR
        QApplication::restoreOverrideCursor();
    #endif        
        recievedNewMessageSignal();

        break;
    }
}

Mini2440Client::~Mini2440Client()
{
    delete pictureFlowWidget;
    delete screenSaveWidget;
    delete messageSlideShowWidget;
    delete m_config;
    tcpSocket->disconnectFromHost();
    tcpSocket->close();
}


void Mini2440Client::populatePictureFlow()
{
    /*
    pictureFlowWidget->setSlideCount(appList.count());

    for (int i=appList.count()-1; i>=0; --i) {
        pictureFlowWidget->setSlide(i, *(appList[i]->getImage()));
        pictureFlowWidget->setSlideCaption(i, appList[i]->getCaption());
    }

    pictureFlowWidget->setCurrentSlide(appList.count()/2);
    */
    pictureFlowWidget->setSlideCount(4);
//    mInbox = new mini2440InboxForm();
//    appList.append(mInbox);
//    pictureFlowWidget->setSlide(0,*( new QImage("./screenshots/MAC/Address-Book.png")));
//    pictureFlowWidget->setSlideCaption(0, QString::fromUtf8("Danh Bạ"));
    mInbox = new mini2440InboxForm();
    appList.append(mInbox);
    pictureFlowWidget->setSlide(INBOX,*( new QImage("./screenshots/MAC/Message.png")));
    pictureFlowWidget->setSlideCaption(INBOX, QString::fromUtf8("Hộp Thư"));

    mSetting = new mini2440SettingForm();
    mSetting->setConfig(m_config);
    appList.append(mSetting);
    pictureFlowWidget->setSlide(SETUP,*( new QImage("./screenshots/MAC/Setting.png")));
    pictureFlowWidget->setSlideCaption(SETUP, QString::fromUtf8("Cài đặt"));

    mChangePass = new mini2440ChangePassForm();
    mChangePass->setConfig(m_config);
    appList.append(mChangePass);
    pictureFlowWidget->setSlide(CHANGEPASS,*( new QImage("./screenshots/MAC/Keychain-Access-icon.png")));
    pictureFlowWidget->setSlideCaption(CHANGEPASS, QString::fromUtf8("Đổi mật khẩu"));


    appList.append(new QWidget());
pictureFlowWidget->setSlideCaption(QUIT, QString::fromUtf8("Thoát"));
    pictureFlowWidget->setCurrentSlide(0);
}

void Mini2440Client::launchApplication(int index)
{
    // NOTE: Clearing the caches will free up more memory for the demo but will cause
    // a delay upon returning, as items are reloaded.
    //pictureFlowWidget->clearCaches();

    if (index == appList.size() -1) {
        qApp->quit();
        return;
    }
    currentIndex = index;
    inputTimer->stop();

    //QObject::connect(appList[index], SIGNAL(demoFinished()), this, SLOT(demoFinished()));
    if (index == INBOX )
        mInbox->find();
    appList[index]->show();
    //mInbox->setParent();
    //mInbox->show();
}

void Mini2440Client::switchToLauncher()
{
    if (currentIndex != -1)
        appList[currentIndex]->close();
    screenSaveWidget->stopShow();
    messageSlideShowWidget->stopShow();
    inputTimer->start();
    setCurrentWidget(pictureFlowWidget);
    pictureFlowWidget->setFocus();
   // raise();
    //activateWindow();
}

void Mini2440Client::recievedNewMessageSignal()// tin hieu nhan duoc Mess
{
    if (currentIndex == INBOX)
        return;
    inputTimer->stop();
    messageSlideShowWidget->startShow();
    setCurrentWidget(messageSlideShowWidget);
    messageSlideShowWidget->setFocus();
}

void Mini2440Client::recievedReadNewMessageSignal()
{
    pictureFlowWidget->setSlide(INBOX, QImage("./screenshots/MAC/NewMessage.png"));
    pictureFlowWidget->setCurrentSlide(INBOX);
    switchToLauncher();
    /*
    messageSlideShowWidget->stopShow();
    inputTimer->start();
    setCurrentWidget(pictureFlowWidget);
    pictureFlowWidget->setFocus();
    */
}

void Mini2440Client::resetInputTimeout()
{
    if (inputTimer->isActive())
        inputTimer->start();
}

void Mini2440Client::inputTimedout()
{
    switchToSlideshow();
}

void Mini2440Client::recievedWrogpassSignal()
{

}

void Mini2440Client::switchToSlideshow()
{
    inputTimer->stop();
    screenSaveWidget->startShow();
    setCurrentWidget(screenSaveWidget);
    screenSaveWidget->setFocus();
}

void Mini2440Client::demoFinished()
{
    currentIndex = -1;
    setCurrentWidget(pictureFlowWidget);
    inputTimer->start();

    // Bring the Fluidlauncher to the foreground to allow selecting another demo
    raise();
    activateWindow();
}

void Mini2440Client::changeEvent(QEvent* event)
{
    if (event->type() == QEvent::ActivationChange) {
        if (isActiveWindow()) {
            if(currentWidget() == pictureFlowWidget) {
                resetInputTimeout();
            } else {
                screenSaveWidget->startShow();
            }
        } else {
            inputTimer->stop();
            screenSaveWidget->stopShow();
            messageSlideShowWidget->stopShow();
        }
    }
    QStackedWidget::changeEvent(event);
}

void Mini2440Client::displayError(QAbstractSocket::SocketError socketError)
{
    switch (socketError) {
    case QAbstractSocket::RemoteHostClosedError:
        break;
    case QAbstractSocket::HostNotFoundError:
        QMessageBox::information(this, tr("Fortune Client"),
                                 tr("The host was not found. Please check the "
                                    "host name and port settings."));
        break;
    case QAbstractSocket::ConnectionRefusedError:
        QMessageBox::information(this, tr("Fortune Client"),
                                 tr("The connection was refused by the peer. "
                                    "Make sure the fortune server is running, "
                                    "and check that the host name and port "
                                    "settings are correct."));
        break;
    default:
        QMessageBox::information(this, tr("Fortune Client"),
                                 tr("The following error occurred: %1.")
                                 .arg(tcpSocket->errorString()));
    }

    //getFortuneButton->setEnabled(true);
}

void Mini2440Client::onDisconnect()
{
    while(1)
    {
        tcpSocket->connectToHost(m_config->getServerIP(),m_config->getServerPort());
        if (tcpSocket->waitForConnected(5000))
            return;
    }
}

void Mini2440Client::save()
{
    qDebug() << m_config->get_screenTimeout();
    inputTimer->setInterval(m_config->get_screenTimeout());
    screenSaveWidget->setSlideInterval(m_config->get_screenInterval());
    inputTimer->stop();
    inputTimer->start();
}
